package HLLib.map;

import HLCode.HLClass;
import HLCode.HLClassManager;
import HLCode.HLClassManager_H;
import HLCode.HLLibObject;
import HLCode.HLObject;
import HLLib.base.HLGraphics;
import HLLib.base.HLGraphics_H;
import HLLib.base.HLImage;
import HLLib.base.HLPoint;
import HLLib.map.HLGoogleMap.HLGoogleMaps;
import HLLib.map.HLGoogleMap.HLMarks;
import HLLib.map.HLGoogleMap.HLMathDouble;

public class HLMKMap extends HLLibObject implements HLMKMap_H {
    public HLClass GetClass(HLClassManager classManager) {
        return classManager.GetLibClass(HLClassManager_H.CLASS_GROUP_TYPE_LIB_MAP, HLClassManager_H.LIB_CLASS_MAP_MKMap);
    }

    public int GetInt(int index) {
        switch (index) {
        case 0: {
            return x;
        }
        case 1: {
            return y;
        }
        case 2: {
            return width;
        }
        case 3: {
            return height;
        }
        case 4: {
            return zoomLevel;
        }
        case 5: {
            return longitude;
        }
        case 6: {
            return latitude;
        }
        }
        return 0;
    }

    public void SetInt(int index, int value) {
        switch (index) {
        case 0: {
            x = value;
            return;
        }
        case 1: {
            y = value;
            return;
        }
        case 2: {
            width = value;
            return;
        }
        case 3: {
            height = value;
            return;
        }
        case 4: {
            zoomLevel = value;
            return;
        }
        case 5: {
            longitude = value;
            return;
        }
        case 6: {
            latitude = value;
            return;
        }
        }
    }

    public HLObject GetObject(int index) {
        return image;
    }

    public void SetObject(int index, HLObject value) {
        image = (HLImage) value;
    }

    public int x;

    public int y;

    public int width;

    public int height;

    public int zoomLevel;

    public int longitude;

    public int latitude;

    private HLGoogleMaps googleMap;

    private int curPosX;

    private int curPosY;

    private boolean visiable;

    public HLImage image;

    public static HLMKMap map;

    private HLPoint curCenterPoint = new HLPoint();

    public HLMKMap() {
        googleMap = new HLGoogleMaps();
        HLMKMap.map = this;

    }

    public void InitByRectAndCenterAndZoom(int x, int y, int width, int height, int latitude, int longitude, int zoomLevel) {
        HLLocation location = new HLLocation(latitude, longitude);
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.zoomLevel = zoomLevel;
        this.latitude = latitude;
        this.longitude = longitude;
        googleMap.SetProperty(width, height, location, 20 * (ZOOM_LEVEL_MAX - zoomLevel) / ZOOM_LEVEL_MAX);
        HLMarks mark = new HLMarks();
        mark.AddPos(longitude, latitude);
        googleMap.AddMarks(mark);
        LoadImage();
        curPosY = (int) HLGoogleMaps.latToPixel(latitude, googleMap.zoom);
        curPosX = (int) HLGoogleMaps.lngToPixel(longitude, googleMap.zoom);
    }

    public void SetCenter(int latitude, int longitude) {
        HLLocation location = new HLLocation(latitude, longitude);
        this.latitude = latitude;
        this.longitude = longitude;
        googleMap.SetProperty(width, height, location, (20 * (ZOOM_LEVEL_MAX - zoomLevel) / ZOOM_LEVEL_MAX));
        LoadImage();
        curPosY = (int) HLGoogleMaps.latToPixel(latitude, googleMap.zoom);
        curPosX = (int) HLGoogleMaps.lngToPixel(longitude, googleMap.zoom);
    }

    public void SetZoom(int zoomLevel) {
        HLLocation location = new HLLocation(latitude, longitude);
        this.zoomLevel = zoomLevel;
        googleMap.SetProperty(width, height, location, (20 * (ZOOM_LEVEL_MAX - zoomLevel) / ZOOM_LEVEL_MAX));
        curPosY = (int) HLGoogleMaps.latToPixel(latitude, googleMap.zoom);
        curPosX = (int) HLGoogleMaps.lngToPixel(longitude, googleMap.zoom);
        LoadImage();
    }

    public void SetZoomAtCentre(int zoomLevel, int x, int y) {

    }

    public void SetZoomAtCentreBySize(int x, int y, int sizeX, int sizeY) {

    }

    public void SetMove(int x, int y) {

        HLLocation location = new HLLocation(latitude, longitude);
        location.latitude = HLGoogleMaps.pixelToLat(curPosY - y, googleMap.zoom);
        location.longitude = HLGoogleMaps.pixelToLng(curPosX - x, googleMap.zoom);
        this.latitude = location.latitude;
        this.longitude = location.longitude;
        googleMap.SetProperty(width, height, location, googleMap.zoom);
        curPosY = curPosY - y;
        curPosX = curPosX - x;
        HLImage tempImage = HLImage.CreateImageBySize(width, height);
        HLGraphics g = tempImage.GetGraphics();
        g.DrawImage(image, x, y, HLGraphics_H.TRANS_NONE);

        image = new HLImage();
        image.image = tempImage.image;

        image.SetSize(width, height);
        googleMap.GetMap(image);
        curCenterPoint.x = (int) HLGoogleMaps.lngToPixel(longitude, googleMap.zoom);
        curCenterPoint.y = (int) HLGoogleMaps.latToPixel(latitude, googleMap.zoom);
    }

    public HLPoint GetPoint(int latitude, int longitude) {
        HLPoint point = new HLPoint();
        point.x = (int) HLGoogleMaps.lngToPixel(longitude, googleMap.zoom);
        point.y = (int) HLGoogleMaps.latToPixel(latitude, googleMap.zoom);

        point.x = width / 2 + point.x - curCenterPoint.x;
        point.y = height / 2 + point.y - curCenterPoint.y;
        return point;
    }

    public HLLocation GetCoordinate(int x, int y) {
        HLLocation location = new HLLocation(latitude, longitude);
        x = x + curCenterPoint.x - width / 2;
        y = y + curCenterPoint.y - height / 2;
        location.latitude = HLGoogleMaps.pixelToLat(y, googleMap.zoom);
        location.longitude = HLGoogleMaps.pixelToLng(x, googleMap.zoom);
        return location;

    }

    public void SetMapType(int type) {
        googleMap.SetMapType(type);
        if (type != googleMap.mapType) {
            LoadImage();
        }
    }

    public void SetVisiable(boolean visiable) {
        this.visiable = visiable;
        if (visiable) {
            HLMKMap.map = this;
        } else {
            HLMKMap.map = null;
        }
    }

    private void LoadImage() {
        image = new HLImage();
        image.SetSize(width, height);
        googleMap.GetMap(image);
        curCenterPoint.x = (int) HLGoogleMaps.lngToPixel(longitude, googleMap.zoom);
        curCenterPoint.y = (int) HLGoogleMaps.latToPixel(latitude, googleMap.zoom);
    }

    public static int GetDistanse(int latitude1, int longitude1, int latitude2, int longitude2) {
        double lat1 = ((float) (latitude1)) / COORDINATE_SCATE_RAT;
        double lon1 = ((float) (longitude1)) / COORDINATE_SCATE_RAT;
        double lat2 = ((float) (latitude2)) / COORDINATE_SCATE_RAT;
        double lon2 = ((float) (longitude2)) / COORDINATE_SCATE_RAT;

        double radius = 6370000;
        double vv = (Math.cos(lat2 * Math.PI / 180.0) * Math.cos(lat1 * Math.PI / 180.0) * Math.cos(lon1 * Math.PI / 180.0 - lon2 * Math.PI / 180.0) + Math.sin(lat1 * Math.PI / 180.0) * Math.sin(lat2 * Math.PI / 180.0));
        double ac = HLMathDouble.acos(vv);
        double distance = radius * ac;
        return (int) distance;
    }

    public HLLocation GetUserLocation() {
        HLLocation newLocation = new HLLocation(4007420, 11631509);
        return newLocation;
    }

    public void UserInteractionEnabled(boolean enabled) {
    }

    public void Update() {
    }
}
